package com.example.day1_kotlin

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}

/**
 * main方法
 * fun(方法，函数) function ,所有被fun标记的都是一个方法
 * main 方法名，主方法和java中一样都是用main命名，是一个关键字
 * args参数名，是一个形参
 * Array<String> 参数类型 string类型的数据
 * 注意：和java不同的是，kotlin声明变量时，名字在前，类型在后，中间用：实现关系
 * 在kotlin中，所有的方法都有返回值，类似java中的void ，但是kotlin中可以省略
 * Unit:相当于java中的void
 */
fun main1(args: Array<String>) {
    //println("Hello World!")
   // println(min(5,3))
    //str = "修改字符串"
    a = 18
    //a = "123"
    list.add("kotlin")
    //list.add(1)
    //println(list)
    //println("你好，${name}欢迎回来")
    //println("1+2=${1+2}")
    //println("a ${if(a>10) "大于10" else "小于等于10"}")
    /*val user:User = User("zll","123",12)
    user.password = "111"
    println(user.password)
    println(user.isAdult)
    val userJava = UserJava("ZLL","111",15)
    println(userJava.isAdult)*/
    //println(getColorString(Color.RED))
    //println(getColorString(Color.YELLOW))
    println(play())
}

/**
 * a:Int a是参数名 Int是参数类型 :在kotlin中有继承、实现、声明类型的意思
 * :Int 代表的是方法的返回值类型是Int类型
 * 注意：在kotlin中所有基本类型首字母都是大写的
 */

/*fun min(a:Int,b:Int):Int{
    return if(a>b) {
        b
    } else {a}
}*/
/**
 * kotlin特性：表达式方法体（函数体）
 * 如果一个方法的方法体是由单个表达式构成，可以用这个表达式作为完成整的方法体，并且去掉大括号和return 语句
 * 同时方法的返回值:Int也可省略
 */
fun min(a:Int,b:Int)= if(a>b) b else a

/**
 * 变量：
 * val(value)不可变变量，在初始化后不能再次赋值，相当于java中的final修饰词
 * var(variable)可变变量，这种变量的值是可以进行修改的，相当于java中的普通变量
 * :String可以省略，也就是val和var可以自动识别类型，初始化是什么类型，后续进行修改时必须是对应的类型
 * 有一种特殊情况，当使用val声明list的时候，集合中的值是可以改变添加的
 */
val str:String = "这是字符串"
var a = 12
val list = arrayListOf("Java")

/**
 * 拼接字符串
 * 使用$符号可以直接在字符串中引用某些变量，设置可以加{}来进行计算或者判断操作
 * 注意写句式的时候，可以先写出完整的字符串，在加入${}
 */
val name = "zll"

/**
 * 枚举
 * 在kotlin中唯一一个用到分号的地方，就是在枚举的构造方法和普通方法的区分
 * 代表换行，是一个方法，而不是一个枚举了
 */
enum class Color(val r:Int,val g:Int,val b:Int){
    RED(255,0,0),
    YELLOW(255,255,0),
    GREEN(0,255,0),
    BLUE(0,0,255);
    fun rgb()=(r*256+g)*256+b//获取颜色的十进制的值
}
/*fun getColorString(color: Color):String{
    when(color){
        Color.RED->return "红色"
        Color.BLUE->return "蓝色"
        Color.YELLOW->return "黄色"
        Color.GREEN ->return "绿色"
        else -> return "不知道什么色"
    }
}*/
/**
 * 分支结构 when
 */
fun getColorString(color: Color)= when(color){
    /*Color.RED-> "红色"
    Color.BLUE-> "蓝色"
    Color.YELLOW-> "黄色"
    Color.GREEN -> "绿色"
    else -> "不知道什么色"*/
    Color.RED,Color.YELLOW-> {"暖色调"}
    Color.GREEN->"中性色"
    Color.BLUE->"冷色调"
}

/**
 * 区间 1..10 指的是1-10并且包含10  1 until 10 1-10不包含10
 * i是形参，写什么都可以，按照for循环的习惯，一遍写作i
 * in 在某个区间内，或者list或者数组
 */
val oneToTen = 1..10
val oneToNine = 1 until 10

fun play(){
   /* for (i in 1..10){
        println("$i")
    }*/
  /*  list.forEach {
        println(it)
    }*/
    /*for (i in 'a'..'f'){
        println("$i")
    }*/
    for (i in 1..100){
        println(getLeap(i))
    }

}
//获取1-100之间可以被4整除的数字
fun getLeap(i:Int) = when{
    i%4==0 -> "闰年"
    else-> "${i}年"
}
//-------------------------------------------------------------------
fun main() {
   /* println("hello".repeat(3))
    "张三".sayHello()*/
    //strnull = stra
    //stra= strnull
    //strnull = null
    //println(getlen())
    //  ((Good)data).
    //val cow =  Anima() as Cow//报错--不能转
   /* val cow = Cow()
    println(getAnima(cow))*/
/*    val fx = FX<Int>(2)
    println(fx.value)
    val fx1 = FX<String>("张三")
    println(fx1.value)
    println(singFx("hello"))*/
/*    println(high {
        it.toString()
    })
    val resultFunc = high2 { it.toString() }
    val res = resultFunc(10)
    println(res)*/
/*    sumNum()
    with(user1){
        println("username是 $username   password是 $password  age是 $age")
    }
    val string = user1.let {
        "Hello,我的名字是${it.username.lowercase()}我今年${it.age+1}岁了"
    }
    println(string)
    val user2 = user1.run {
        User(this.username.lowercase(),this.password,this.age+10)
    }
    println("新的用户${user2.username} 年龄是${user2.age}")
    val user3 = user1.apply {
        username = username.lowercase()
    }
    val user4 = user1.apply {
         username.lowercase()//username不会更新
    }
    println("apply出的用户${user3.username}年龄是${user3.age}")
    println("apply出的2用户${user4.username}年龄是${user4.age}")*/
    /*println(getString("张三"){"祝你每天开心快乐"})
    println(getString("李四"){"祝你每天健健康康"})
    println(getString2("王五"){
        "祝你$it 岁生日快乐"
    })*/
    println(varlist)
    varlist.swap(0,2)
    println(varlist)
}
/**
 * 扩展函数--泛型  交换两个元素的位置
 */
fun <T> MutableList<T>.swap(index1:Int,index2:Int){
    //获取下标为index1的值
    val val1 = this[index1]
    //将下标为index2的值  赋值给  下标为index1的值
    this[index1] = this[index2]
    //将最开始下标为index1的值  赋值给 下标为index2的值
    this[index2] = val1
}
var varlist = mutableListOf("Java","Kotlin","ios")

/**
 * inline优化
 */
fun getString(name:String,mess:()->String){
    println("Hello $name ,${mess()}")
}
fun getString2(name:String,mess: (Int) -> String){
    println("Hello $name,${mess(18)}")
}
/**
 * with用法  with(对象)
 * 两个参数：对象user1 lambda表达式 可直接获取其成员字段不用使用关键字it
 * let用法： 对象.let{}
 * 两个参数：对象user1 lambda表达式 使用关键词it来获取其成员字段
 * run用法  对象.run{}
 * 两个参数：对象user1 lambda表达式 使用关键词ithis来获取其成员字段的值 常用于初始化或者配置
 * apply用法：对象.apply{}
 * 两个参数：对象user1 lambda表达式 可以获取其成员字段不需使用关键词this, 返回的不是表达式的结果 而是对象本事 （需要赋值给字段本身才能修改成功）
 */
val user1 = User("ZLL","111",18)

/**
 * lambda表达式使用案例---定义一个数字， 过滤大于5的数字，并结算他们的和
 */
var list3= listOf(1,2,3,4,5,6,7,8,9,10)
fun sumNum(){
    val oushu = list3.filter {
        it%2==0}
    println(oushu)
    val sumhe = oushu.sumOf { it*2 }
    println(sumhe)
}



/**
 * 高阶函数
 * arg:(Int)->String:函数中的参数 这个参数是一个函数（方法） arg：函数名，可任意起名  (Int)->String函数体：把数字转成字符串
 * :String 最终的返回值类型
 */
fun high(abc:(Int)->String):String{
    return abc(5)
}

/**
 * 高阶函数2  参数是一个函数  返回值是同一个函数
 */
fun high2(arg:(Int)->String):(Int)->String{
    return arg
}

/**
 * 泛型类
 */
class FX<V>(v:V){
    var value = v
}
//泛型函数--类比mvp中fragment方法中的findViewById
fun <T> singFx(t:T):List<T>{
    return listOf(t)
}

/**
 * 智能转化
 * is  instanceof可以理解为 是
 * as 强转  类似java中 （Good.DataBean）good
 *
 * 密封类：在进行when判断时，需要将所有的分支都要添加上，不需要添加else
 */
sealed class Anima
class Pig:Anima()
class Cow:Anima()

class Sheep:Anima()

fun getAnima(anima: Anima)=when(anima){
    is Pig->"猪"
    is Cow->"牛"
    is Sheep->"羊"
}

/**
 * 扩展方法
 * String.扩展方法的类型
 * sayHello()：扩展方法的方法名
 */
fun String.sayHello(){
    println("Hello,$this")//具体操作

}
/**
 * 空安全
 * 不可空变量 可以赋值给  可空变量，反之不可
 * 使用？来定义可为空
 * ！！代表该字段一定不为null，当为null时，报错
 * ?: 当变量不为null时，使用左侧的值，否则使用右侧的值
 */
var strnull:String? = ""//可空变量

var stra = "张三"//不可空变量

fun getlen():Int = strnull!!.length
fun getlen1():Int = strnull?.length ?: -1














